package com.ljq.rpc.server.config;

import com.ljq.rpc.annotations.Register;
import com.ljq.rpc.annotations.ServerComponent;
import com.ljq.rpc.codec.JSONDecoder;
import com.ljq.rpc.codec.JSONEncoder;
import com.ljq.rpc.server.handler.NettyServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

@ServerComponent
@Register
public class NettyServer {

    private final ServerConfig serverConfig;

    public NettyServer(ServerConfig serverConfig) throws InterruptedException {
        System.out.println("开始注入nettyServer");
        this.serverConfig = serverConfig;
        startServer(serverConfig);
    }

    public void startServer(ServerConfig serverConfig) throws InterruptedException {
        new Thread(()->{
            try {
                startServer0(serverConfig);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        System.out.println("服务器开始提供服务");
    }

    void startServer0(ServerConfig serverConfig) throws InterruptedException {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new JSONDecoder());
                            pipeline.addLast(new JSONEncoder());
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });
            ChannelFuture channelFuture = serverBootstrap.bind(serverConfig.getPort()).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}
